﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using ProjectRoughWork.Engine.SoundManager;

namespace ProjectRoughWork
{
    class Demolition : SquadActor
    {
        public enum AttackState { Optimal, Unoptimal };

        /// <summary>
        /// Default constructor. Initializes the unit type
        /// </summary>

        public Demolition(string modelType)
            : base()
        {
            unitType = "Demolition";
            state = AttackState.Optimal;


            //Initialize the parameters of the Demolition Unit

            maxVel = 2.0f;

            maxHealth = 1000f;
            currentHealth = maxHealth;
            gunRange = 400;
            gunFireRate = 5000f;



            //Assign the model name to be loaded
            modelName = modelType;


            InitVertices();
            
             //Initialize the origin and bounding sphere of the demo unit

            mOrigin = new Vector3(mPos.X + size/2, mPos.Y + size/2, mPos.Z + size/2);
            bSphere = new BoundingSphere(mOrigin, size);
        }

        //Sets up stuff for placeholder model

        public void InitVertices()
        {
            size = 20;

            //Store previous device state and content state
            GraphicsDevice oldDevice = Game1.GetGraphicsDevice();
            ContentManager oldContent = Game1.GetContentManager();
           
            demolition =new SkinnedModel(oldContent.Load<Model>(modelName),
               getPosition(), Vector3.Up*getRotation(), new Vector3(size/15),
               oldDevice,
               oldContent);

            demolition.Player.StartClip("Run", TimeSpan.FromMilliseconds(0),
                                TimeSpan.FromMilliseconds(1), false);
               // transforms = new Matrix[demolition.Bones.Count];
               // demolition.CopyAbsoluteBoneTransformsTo(transforms);

            rifle = Game1.GetContentManager().Load<Model>("nerf design");

            handIndex = demolition.Model.Bones["R_Hand"].Index - 13;

            vertices = new VertexPositionColorTexture[8];

            vertices[0].Position = new Vector3(0, 0, 0);
            vertices[0].Color = Color.Gold;

            vertices[1].Position = new Vector3(0, size, 0);
            vertices[1].Color = Color.Gold;

            vertices[2].Position = new Vector3(size, size, 0);
            vertices[2].Color = Color.Gold;

            vertices[3].Position = new Vector3(size, 0, 0);
            vertices[3].Color = Color.Gold;

            vertices[4].Position = new Vector3(0, 0, size);
            vertices[4].Color = Color.Gold;

            vertices[5].Position = new Vector3(0, size, size);
            vertices[5].Color = Color.Gold;

            vertices[6].Position = new Vector3(size, size, size);
            vertices[6].Color = Color.Gold;

            vertices[7].Position = new Vector3(size, 0, size);
            vertices[7].Color = Color.Gold;

            short[] temp = {
                               0,1,2,       //Front
                               2,3,0,
                               4,5,1,       //Left
                               1,0,4,
                               4,5,6,       //Back
                               6,7,4,
                               3,2,6,       //Right
                               6,7,3,
                               0,4,7,       //Bottom
                               7,3,0,
                               1,5,6,       //Top
                               6,2,1
                           };

            indices = temp;
        }

        /// <summary>
        /// Property for the current attack state of the demolition unit
        /// </summary>

        public AttackState CurrentAttackState
        {
            get { return state; }
            set { state = value; }
        }

        public override bool Shoot(Vector3 target)
        {
            if (canFire)
            {
                canFire = false;

                //Create a nerf dynamite actor and the AI to manipulate the dynamite, place them in their respective events and queue them

                NerfDynamite nerf = new NerfDynamite(mPos, mID);
                NerfDynamiteAI nerfAI = new NerfDynamiteAI(nerf, target, (GameplayScreen)ScreenManager.GetInstance().getTop());   //Need to fix

                EventAddActor addEvt = new EventAddActor(nerf);
                EventAttachProcess attachEvt = new EventAttachProcess(nerfAI);

                EventManager.GetInstance().VQueueEvent(addEvt);
                EventManager.GetInstance().VQueueEvent(attachEvt);

                // Play the sound effect
                SoundManager.GetInstance().playSound(this.Position, SoundManager.FIRE_DEMOLITION);

                Firing = true;
                return true;
            }

            Firing = false;
            return false;
        }

        public override void VOnUpdate()
        {
            base.VOnUpdate();
            if (demolition.Player.Done)
            {
                if (Moving)
                {
                    demolition.Player.StartClip("Run", TimeSpan.FromMilliseconds(0),
                                  TimeSpan.FromMilliseconds(800), false);
                }

                if (Firing)
                {
                    demolition.Player.StartClip("Shoot", TimeSpan.FromMilliseconds(0),
                                         TimeSpan.FromMilliseconds(600), false);
                }

                if (isDead())
                    demolition.Player.StartClip("Idle", true);
            }
            demolition.Update(Game1.GetGameTime());

        }

        public override void VRender()
        {
            GraphicsDevice device = Game1.GetGraphicsDevice();

            Effect customEffect = Game1.GetCustomEffect();
            customEffect.Parameters["World"].SetValue(Matrix.CreateTranslation(mPos));

            //Remember old graphics device 
            BlendState tempBlend = Game1.GetGraphicsDevice().BlendState;
            DepthStencilState tempDepth = Game1.GetGraphicsDevice().DepthStencilState;
            RasterizerState tempRasterizer = Game1.GetGraphicsDevice().RasterizerState;
            SamplerState tempSample = Game1.GetGraphicsDevice().SamplerStates[0];

            //Calculate the starting world matrix for marine model
            Matrix baseWorld = Matrix.CreateScale(3.0f) *
                Matrix.CreateRotationY(mRotation + MathHelper.PiOver2) *
                /*
                Matrix.CreateRotationY(NormalizeRotation(90)) * 
                Matrix.CreateRotationY(NormalizeRotation(mRotation)) *          //Shakir Edit March 30th, 2011 - Fixed Rotation
                Matrix.CreateRotationY(NormalizeRotation(-90)) * */
                customEffect.Parameters["World"].GetValueMatrix();



            /*    foreach (ModelMesh mesh in demolition.Meshes)
                {
                    Matrix localWorld = transforms[mesh.ParentBone.Index]
                        * baseWorld;
                    foreach (ModelMeshPart part in mesh.MeshParts)
                    {

                        BasicEffect e = (BasicEffect)part.Effect;
                */
                        //reset the graphics device to the default state to draw the solid model
                        //Without this model textures appear transparent
                        device.BlendState = BlendState.Opaque;
                        device.DepthStencilState = DepthStencilState.Default;
                        device.RasterizerState = RasterizerState.CullCounterClockwise;
                        device.SamplerStates[0] = SamplerState.LinearWrap;

                        demolition.Draw(customEffect.Parameters["View"].GetValueMatrix(), 
                            customEffect.Parameters["Projection"].GetValueMatrix(),
                            baseWorld);

                        foreach (ModelMesh mesh in rifle.Meshes)
                        {
                            foreach (BasicEffect effect in mesh.Effects)
                            {

                                //Grenade Launcher
                                Matrix rifleTransform = Matrix.CreateScale(0.5f) *
                                  Matrix.CreateTranslation(new Vector3(4.0f, 10.0f, 11.0f)) *
                                    Matrix.CreateFromYawPitchRoll(MathHelper.PiOver2, -0.45f,
                                  MathHelper.Pi + 1.0f);  

                                effect.World = rifleTransform *
                                   demolition.Player.WorldTransforms[handIndex] * baseWorld;

                                effect.View = customEffect.Parameters["View"].GetValueMatrix();
                                effect.Projection = customEffect.Parameters["Projection"].GetValueMatrix();
                               
                            }

                            mesh.Draw();
                        }

             /*             
                        e.World = localWorld;
                        e.View = Game1.GetBasicEffect().View;
                        e.Projection = Game1.GetBasicEffect().Projection;
                        e.LightingEnabled = true;
                        e.EnableDefaultLighting();
                    }

                    mesh.Draw();
                }
                */
            //Call render for model
            base.VRender();

            //reset the graphics device to the previous state
              device.BlendState = tempBlend;
              device.DepthStencilState = tempDepth;
              device.RasterizerState = tempRasterizer;
              device.SamplerStates[0] = tempSample;


           /* foreach (EffectPass pass in customEffect.CurrentTechnique.Passes)
            {
                pass.Apply();

                device.DrawUserIndexedPrimitives<VertexPositionColorTexture>(PrimitiveType.TriangleList, vertices, 0, vertices.Length, indices, 0, indices.Length / 3);
            }*/

            base.VRender();
        }

        //Data Member

        VertexPositionColorTexture[] vertices;
        short[] indices;
        int size;

        AttackState state;                          //The Current Attack State of the Demolition Unit

        //Members Added
        //Model demolition;
       // Matrix[] transforms;
        SkinnedModel demolition;
        Model rifle;
        int handIndex;
    }
}
